package com.lzyyj.gmis.base.model;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.model.PicturesTable;
import org.apache.poi.hwpf.usermodel.CharacterRun;
import org.apache.poi.hwpf.usermodel.Paragraph;
import org.apache.poi.hwpf.usermodel.Picture;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.hwpf.usermodel.Table;
import org.apache.poi.hwpf.usermodel.TableCell;
import org.apache.poi.hwpf.usermodel.TableIterator;
import org.apache.poi.hwpf.usermodel.TableRow;
import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.xwpf.usermodel.Document;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFPicture;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.XmlCursor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;

public class WordFile {

	/**
	 * Word2003版本后缀名
	 */
	private final static String DOC = "doc";

	/**
	 * Word2007以上版本后缀名
	 */
	private final static String DOCX = "docx";

	/**
	 * 系统临时文件路径
	 */
	private final static String SYSTEM_TEMPORARY_PATH = System.getProperty("java.io.tmpdir");
	/**
	 * 
	 */
	private OPCPackage oPCPackage;
	private XWPFDocument xwpfDocument;

	private FileInputStream fileInputStream;
	private POIFSFileSystem poifsFileSystem;
	private HWPFDocument hwpfDocument;
	
	public WordFile(String pathName) {
		File file = new File(pathName);
		parseWorld(file);
	}
	
	public WordFile(File file) {
		parseWorld(file);
	}

	private void parseWorld(File file) {
		String suffixName = file.getPath().split("\\.")[1];
		try {
			if (DOCX.equals(suffixName)) {
				oPCPackage = POIXMLDocument.openPackage(file.getPath());
				xwpfDocument = new XWPFDocument(oPCPackage);
			}
			if (DOC.equals(suffixName)) {
				fileInputStream = new FileInputStream(file);
				poifsFileSystem = new POIFSFileSystem(fileInputStream);
				hwpfDocument = new HWPFDocument(poifsFileSystem);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static WordFile getInstance(File file) {
		
		return new WordFile(file);

	}

	/**
	 * 取出word文档表格第cellRowIdx行，第cellColIdx列的值（DOCX）
	 * 
	 * @param file       解析文件
	 * @param cellRowIdx 行
	 * @param cellColIdx 列
	 */
	@SuppressWarnings("unused")
	public String getSpecifyDataForDocx(int cellRowIdx, int cellColIdx) {
		try {
			// 获取页面中的表格
			Iterator<XWPFTable> it = xwpfDocument.getTablesIterator();
			while (it.hasNext()) {
				// 循环页面中的表格
				XWPFTable table = (XWPFTable) it.next();
				StringBuffer str = new StringBuffer();
				// 获取表格中的行
				XWPFTableRow row = table.getRow(cellRowIdx);
				// 获取行中共有多少列
				List<XWPFTableCell> cells = row.getTableCells();
				// 获取列
				XWPFTableCell cell = cells.get(cellColIdx);
				// 获取列中的段落
				StringBuffer allFilePath = new StringBuffer();
				for (int i = 0; i < cell.getParagraphs().size(); i++) {
					List<XWPFRun> runs = cell.getParagraphs().get(i).getRuns();
					for (int j = 0; j < runs.size(); j++) {
						// 获取单个对象
						XWPFRun r = runs.get(j);
						String text = r.getText(r.getTextPosition());
						// 如果字符为空，可能是附件一类的文件，比如图片之类的，需要另外解析,此处处理为图片
						if (text == null) {
							List<XWPFPicture> piclist = r.getEmbeddedPictures();
							for (int k = 0; k < piclist.size(); k++) {
								String filePath = SYSTEM_TEMPORARY_PATH + UUID.randomUUID() + ".jpg";
								XWPFPicture pic = piclist.get(k);
								byte[] picbyte = pic.getPictureData().getData();
								// 将图片写入本地文件
								@SuppressWarnings("resource")
								FileOutputStream fos = new FileOutputStream(filePath);
								fos.write(picbyte);
								allFilePath.append(filePath);
							}
						} else {
							allFilePath.append(text);
						}
					}
				}
				return allFilePath.toString();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 关闭
	 */
	public void closeForDocx() {
		try {
			oPCPackage.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 取出word文档表格第cellRowIdx行，第cellColIdx列的值（DOC）
	 * 
	 * @param file       解析文件
	 * @param cellRowIdx 行
	 * @param cellColIdx 列
	 */
	@SuppressWarnings({ "resource", "unused" })
	public String getSpecifyDataForDoc(int cellRowIdx, int cellColIdx) {
		try {
			Range range = hwpfDocument.getRange();
			TableIterator it = new TableIterator(range);
			PicturesTable picturesTable = hwpfDocument.getPicturesTable();
			while (it.hasNext()) {
				Table tb = (Table) it.next();
				TableRow tr = tb.getRow(cellRowIdx);
				TableCell td = tr.getCell(cellColIdx);
				CharacterRun cr = td.getCharacterRun(0);
				if (picturesTable.hasPicture(cr)) {
					Picture pic = picturesTable.extractPicture(cr, true);
					byte[] picbyte = pic.getContent();
					String filePath = SYSTEM_TEMPORARY_PATH + UUID.randomUUID() + ".jpg";
					// 将图片写入本地文件
					FileOutputStream fos = new FileOutputStream(filePath);
					fos.write(picbyte);
					return filePath;
				} else {
					for (int k = 0; k < td.numParagraphs(); k++) {
						Paragraph para = td.getParagraph(k);
						String s = para.text();
						s = s.substring(0, s.length() - 1);
						return s;
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public void test(File file) {
		XWPFDocument doc = null;

		InputStream in = null;
		OutputStream out = null;
		try {
			in = new FileInputStream(file);
			doc = new XWPFDocument(in);

			// 文本替换
			Map<String, String> param = new HashMap<String, String>();
			param.put("PartyA", "我是甲方");
			param.put("PartyB", "我是乙方");
			param.put("date", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
			param.put("text", "合同内容合同内容合同内容合同内容合同内容合同内容合同内容合同内容合同内容合同内容合同内容合同内容合同内容");
			List<XWPFParagraph> allXWPFParagraphs = doc.getParagraphs();
			for (XWPFParagraph xwpfParagraph : allXWPFParagraphs) {
				List<XWPFRun> runs = xwpfParagraph.getRuns();
				for (XWPFRun run : runs) {
					String text = run.getText(0);
					if (StringUtils.isNoneBlank(text)) {
						if (text.equals("table")) {
							// 表格生成 6行5列.
							int rows = 6;
							int cols = 5;
							XmlCursor cursor = xwpfParagraph.getCTP().newCursor();
							XWPFTable tableOne = doc.insertNewTbl(cursor);

							// 样式控制
							CTTbl ttbl = tableOne.getCTTbl();
							CTTblPr tblPr = ttbl.getTblPr() == null ? ttbl.addNewTblPr() : ttbl.getTblPr();
							CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
							CTJc cTJc = tblPr.addNewJc();
							cTJc.setVal(STJc.Enum.forString("center"));// 表格居中
							tblWidth.setW(new BigInteger("9000"));// 每个表格宽度
							tblWidth.setType(STTblWidth.DXA);

							// 表格创建
							XWPFTableRow tableRowTitle = tableOne.getRow(0);
							tableRowTitle.getCell(0).setText("标题");
							tableRowTitle.addNewTableCell().setText("内容");
							tableRowTitle.addNewTableCell().setText("姓名");
							tableRowTitle.addNewTableCell().setText("日期");
							tableRowTitle.addNewTableCell().setText("备注");
							for (int i = 1; i < rows; i++) {
								XWPFTableRow createRow = tableOne.createRow();
								for (int j = 0; j < cols; j++) {
									createRow.getCell(j).setText("我是第" + i + "行,第" + (j + 1) + "列");
								}
							}
							run.setText("", 0);
						} else {
							for (Entry<String, String> entry : param.entrySet()) {
								String key = entry.getKey();
								if (text.indexOf(key) != -1) {
									text = text.replace(key, entry.getValue());
									run.setText(text, 0);
								}
							}
						}
					}
				}
			}
			out = new FileOutputStream("D:\\report.doc");
			// 输出
			doc.write(out);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null) {
					out.close();
				}

				if (in != null) {
					in.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}
